<template>
	<view v-if="formList.length">
		<u-form :model="form" ref="uForm" :label-width="labelWidth" :label-position="labelPosition"
			:border-bottom="borderBottom" :labelStyle="labelStyle">
			<view :style="[itemStyle,item.style]" :key="item.prop" v-for="(item,index) in formList">
				<slot v-if="item.type == 'slot'" :name="item.prop"></slot>
				<u-form-item :required="showRedDot && item.required" :left-icon="item.leftIcon"
					:left-icon-style="item.leftIconStyle" :prop="item.prop" :label="item.label" v-else-if="!item.hide">
					<block v-if="item.type == 'radio'">
						<u-radio-group v-model="form[item.prop]" :active-color="themeColor">
							<u-radio v-for="(radio, idx) in item.options" :key="idx" :name="radio.name">
								{{ radio.name }}
							</u-radio>
						</u-radio-group>
					</block>

					<block v-else-if="item.type == 'checkbox'">
						<u-checkbox-group @change="checkboxGroupChange">
							<u-checkbox v-model="el.check" v-for="(el, idx) in item.options" :key="index"
								:name="item.name">{{item.name}}</u-checkbox>
						</u-checkbox-group>
					</block>

					<block v-else-if="item.type == 'select' && requestFinish">
						<u-input :inputAlign="inputAlign" :value="findLabel(item,form[item.prop])" type="select"
							:placeholder="getPlaceholder(item)" @click="handleOpenSelect(item)" />
					</block>


					<block v-else-if="item.type == 'picker'">
						<u-input :inputAlign="inputAlign" v-model="form[item.prop]" type="select"
							:placeholder="getPlaceholder(item)" @click="handleOpenPicker(item)" />
					</block>

					<block v-else-if="item.type == 'upload'">
						<u-upload :del-icon="item.uploadProps.delIcon || 'close'"
							:del-color="item.uploadProps.delColor || '#fff'"
							:del-bg-color="item.uploadProps.delBgColor || '#fa3534'"
							:width="item.uploadProps.width || 200" :height="item.uploadProps.height || 200"
							:upload-text="getPlaceholder(item)" :show-progress="item.uploadProps.showProgress"
							:max-count="item.uploadProps.maxCount || 1" :name="item.uploadProps.file || 'file'"
							:form-data="item.uploadProps.formData" :action="item.uploadProps.action"
							:header="item.uploadProps.header"
							@on-success="(data, index, lists, name)=>handleUploadSuccess(data, index, lists, name,item)"></u-upload>
					</block>

					<block v-else>
						<u-input :disabled="item.disabled" :inputAlign="inputAlign" :type="item.inputType || 'text'"
							v-model="form[item.prop]" :placeholder="getPlaceholder(item)"
							:maxlength="item.maxlength || 100" :password-icon="item.passwordIcon">
						</u-input>

					</block>
					<template v-slot:right="" v-if="item.right">
						<slot name="inputRight" :value="form"></slot>
					</template>
				</u-form-item>
			</view>
		</u-form>

		<u-select v-model="showSelect" :mode="selectConfig.mode" :list="selectConfig.data"
			:label-name="selectConfig.labelName" :value-name="selectConfig.valueName"
			@confirm="handleConfirm"></u-select>

		<u-picker :mode="pickerConfig.mode" v-model="showPicker" :params="pickerConfig.params"
			:start-year="pickerConfig.startYear" @confirm="handleConfirmPicker"></u-picker>

	</view>
</template>

<script>
	import request from '@/common/js/http.js';
	export default {
		name: "k-base-form",
		props: {
			defaultData: {
				type: Object,
				default: _ => {}
			},
			formList: {
				type: Array,
				required: true
			},
			labelWidth: {
				type: [String, Number],
				default: 200
			},
			labelPosition: {
				type: String,
				default: "left"
			},
			labelStyle: {
				type: Object,
				default: _ => {}
			},
			itemStyle: {
				type: Object,
				default: _ => {}
			},
			borderBottom: {
				type: Boolean,
				default: true
			},
			// 是否显示红点
			showRedDot: {
				type: Boolean,
				default: true
			},
			// 输入框文字对齐方式
			inputAlign: {
				type: String,
				default: "left"
			}
		},
		data() {
			return {
				showSelect: false,
				showPicker: false,
				selectDataMps: {

				},
				selectConfig: {
					mode: "single-column",
					labelName: "id",
					valueName: "name",
					data: [],
				},
				pickerConfig: {
					mode: "time",
					startYear: this.$k.getNowDate().year,
					params: {
						year: true,
						month: true,
						day: true,
					}
				},
				form: {},
				rules: {},
				// 所有请求是否完成
				requestFinish: true,
			}
		},
		watch: {
			defaultData: {
				handler(v) {
					this.initValue();
				},
				deep: true
			}
		},
		created() {
			this.initForm(this.formList);
		},
		mounted() {
			// #ifdef MP-WEIXIN
			this.$refs.uForm.setRules(this.rules);
			// #endif
		},
		methods: {
			handleUploadSuccess(data, index, lists, name, formItem) {
				const {
					uploadProps,
					prop,
					urlKey
				} = formItem;
				let maxCount = uploadProps.maxCount || 1;
				if (maxCount <= 1) {
					this.form[prop] = '/' + this.$k.getObjDeepProps(data, urlKey);
				} else {
					this.form[prop] = lists;
				}
			},
			findLabel(item, id) {
				if (!item.customSelect && id) {
					const {
						config
					} = item;
					const data = (config.data && config.data.length) ? config.data : this.selectDataMps[item.prop];
					let value = data.find(option => option[config.valueName] == id);
					return value ? value[config.labelName] : value;
				};
				return id
			},
			handleConfirmPicker(obj) {
				let mode = this.pickerConfig.mode;
				let defaultValueKeys = this.pickerConfig.defaultValueKeys;
				let value = "";
				if (mode == 'time') {
					let {
						day,
						hour,
						minute,
						month,
						year
					} = obj
					value = `${year}-${month}-${day} ${hour}:${minute}`
				} else if (mode == "region") {
					this.form[`${mode}Value`] = new Object();
					Object.keys(obj).forEach((key, index) => {
						if (Array.isArray(defaultValueKeys)) {
							this.form[`${mode}Value`][defaultValueKeys[index]] = obj[key]['value'];
						} else {
							this.form[`${mode}Value`][key] = obj[key]['value'];
						};
						value += obj[key]['label']
					})
				}
				this.form[this.pickerConfig.prop] = value
			},
			handleConfirm(arr) {
				let [{
					value,
					label
				}] = arr;

				this.$set(this.form, this.selectConfig.prop, String(value))
			},
			initForm(formList) {
				let requestCount = 0;
				if (Array.isArray((formList))) {
					formList.forEach(async (item) => {
						let defaultValue = ""
						if (!!item.value) {
							defaultValue = item.value;
						}
						if (item.api && typeof item.api == 'string') {
							requestCount++;
							this.requestFinish = false;
							let res = await request.get(item.api);
							this.selectDataMps[item.prop] = res.data.list;
							// item.config.data.push(...res.data.list);
							requestCount--;
							if (!requestCount) {
								this.requestFinish = true;
							};
							/* 							request.get(item.api).then(res => {
															item.config.data.push(...res.data.list);
															requestCount--;
															if (!requestCount) {
																this.requestFinish = true;
															};
														}); */
						};
						this.$set(this.form, item.prop, defaultValue);
					});
				}
				this.setRules();
				this.initValue();
			},
			initValue() {
				if (this.defaultData && Object.keys(this.defaultData).length) {
					this.formList.forEach(item => {
						if (item.config && Array.isArray(item.config.defaultValueKeys) && item.type == 'picker') {
							let mode = item.config.mode;
							this.form[`${mode}Value`] = new Object();
							item.config.defaultValueKeys.forEach(key => {
								this.$set(this.form[`${mode}Value`], key, this.defaultData[key]);
							})
						}
						this.$set(this.form, item.prop, this.defaultData[item.prop]);
					});
				}
			},
			setRules() {
				this.formList.forEach(item => {
					if (item.required) {
						this.getPropRule(item.prop).push({
							required: true,
							message: this.getPlaceholder(item),
							trigger: ['blur', 'change']
						});
					};

					if (item.isConfirmPwd) {
						this.getPropRule(item.prop).push({
							message: this.$t('public.confirmPasswordError'),
							// 触发器可以同时用blur和change
							trigger: ['change', 'blur'],
							validator: (rule, value, callback) => {
								return this.form[item.passwordKey] == value;
							},
						});
					}

					if (item.hasOwnProperty("rules")) {
						if (Array.isArray(item.rules)) {
							let ruleList = item.rules.map(rule => {
								if (rule.hasOwnProperty("pattern")) {
									rule = this.patternRuleHandle(rule);
								}
								return rule;
							})
							this.getPropRule(item.prop).push(...ruleList);
						} else {
							let obj = new Object
							if (item.rules.hasOwnProperty("pattern")) {
								this.getPropRule(item.prop).push(this.patternRuleHandle(item.rules));
							} else {
								this.getPropRule(item.prop).push(item.rules);
							}
						}
					}
				})

			},
			patternRuleHandle(rule) {
				let regex = new RegExp(rule.pattern);
				rule.pattern = regex;
				return rule;
			},
			getPropRule(prop) {
				if (!this.rules.hasOwnProperty(prop)) {
					this.$set(this.rules, prop, []);
				}
				return this.rules[prop];
			},
			getPlaceholder(item) {
				let placeholder = "";
				if (item.placeholder) {
					placeholder = item.placeholder;
				} else {
					placeholder = (item.type == 'select' || item.type == 'radio' || item.type == 'upload') ?
						`请选择${item.label}` :
						`请输入${item.label}`;

				}
				return placeholder;
			},
			handleOpenSelect(item) {
				const {
					prop,
					config
				} = item;
				if (!item.customSelect) {
					this.selectConfig = {
						...config,
						data: (config.data && config.data.length) ? config.data : this.selectDataMps[prop],
						prop
					};
					this.showSelect = true;
				} else {
					this.$emit('openSelect', {
						vm: this,
						prop
					})
				}

			},
			handleOpenPicker(item) {
				this.pickerConfig = {
					...item.config,
					prop: item.prop
				}

				this.showPicker = true
			},

			submit() {
				let data;
				this.$refs.uForm.validate(valid => {
					if (valid) {
						data = this.form;
						if (this.defaultData.id) data.id = this.defaultData.id;
					} else {
						data = false;
					};
				});
				return data;
			}
		}
	}
</script>

<style lang="scss" scoped>

</style>